home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 6 code / TCP / NewsWatcher / NW Source / Source / dialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-26  |  67.7 KB  |  2,701 lines  |  [TEXT/MMCC]

  1. /*----------------------------------------------------------------------------
  2.  
  3.     dialog.c
  4.  
  5.     This module handles dialog windows.
  6.     
  7.     Copyright © 1994-1995, Northwestern University.
  8.  
  9. ----------------------------------------------------------------------------*/
  10.  
  11. #include <stdio.h>
  12. #include <ctype.h>
  13. #include <string.h>
  14.  
  15. #include <Icons.h>
  16.  
  17. #include "glob.h"
  18. #include "dialog.h"
  19. #include "newswatcher.h"
  20. #include "popuputil.h"
  21. #include "menus.h"
  22. #include "tescroll.h"
  23. #include "strutil.h"
  24. #include "text.h"
  25. #include "drawutil.h"
  26. #include "memutil.h"
  27. #include "windutil.h"
  28. #include "wind.h"
  29. #include "resutil.h"
  30. #include "teutil.h"
  31. #include "ic.h"
  32. #include "net.h"
  33.  
  34.  
  35.  
  36. #define kNewsWatcherSmallIconID        128        /* Small program icon */
  37.  
  38. #define kErrDlg                        130        /* Error message dialog */
  39. #define kNoteDlg                    141        /* Note message dialog */
  40. #define kCautionDlg                    142        /* Caution message dialog */
  41. #define kErrAlert                    501        /* Error message alert */
  42. #define kOutOfMemoryDlg                167        /* Out of memory dialog */
  43.  
  44. #define kUnexpectedErrDlg            143        /* Unexpected error dialog */
  45.  
  46. #define kDlgDNRErr                163            /* DNR error dialog */
  47. #define kDlgOpenStreamErr        164            /* Open stream error dialog */
  48. #define kDlgLostConnectionErr    165            /* Lost connection error dialog */
  49.  
  50. #define kServerErrMessageText            129        /* Server error message TEXT resource id */
  51. #define kServerConnectErrMessageText    130        /* Server error msg connect TEXT rsrc id */
  52. #define kServerErrDlg                    128        /* Server error message dialog */
  53. #define kServerErrScrollingTextItem        4        /* item number of scrolling text field */
  54.  
  55. #define kDefaultButtonOutlineUserItemDitlID    400
  56.  
  57.  
  58.  
  59. static Boolean gHandled;        /* true if filter proc handled event */
  60. static short gItem;                /* item number hit in filter proc, or 0 if none */
  61. static EventRecord *gEv;        /* filter proc event record */
  62.  
  63. static short gServerErrInfoType;        /* index in STR# 128 resource of type of server */
  64. static CStr255 gServerErrInfoHost;        /* server address */
  65.  
  66. static TEClickLoopUPP gAutoScrollUPP;
  67. static ControlActionUPP gScrollActionUPP;
  68. static UserItemUPP gScrollingTextFieldUserItemUPP;
  69. static UserItemUPP gDlgDefaultButtonOutlineItemUPP;
  70. static AEIdleUPP gAEIdleProcUPP;
  71.  
  72.  
  73. /* The following global variables are exported. */
  74.  
  75. ModalFilterUPP gDialogFilterUPP;
  76. UserItemUPP gDlgGrayBorderItemUPP;
  77.  
  78.  
  79.  
  80. /*----------------------------------------------------------------------------
  81.     DlgGetCheck 
  82.     
  83.     Get the state of a checkbox in a dialog.
  84.     
  85.     Entry:    dlg = pointer to dialog.
  86.             item = item number of checkbox control.
  87.             
  88.     Exit:    function result = true if checked, false if unchecked.
  89. ----------------------------------------------------------------------------*/
  90.  
  91. Boolean DlgGetCheck (DialogPtr dlg, short item)
  92. {
  93.     Handle itemHandle;
  94.     short itemType;
  95.     Rect box;
  96.     
  97.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  98.     return (GetControlValue((ControlHandle)itemHandle) == 1);
  99. }
  100.  
  101.  
  102.  
  103. /*----------------------------------------------------------------------------
  104.     DlgSetCheck 
  105.     
  106.     Set the state of a checkbox in a dialog.
  107.     
  108.     Entry:    dlg = pointer to dialog.
  109.             item = item number of checkbox control.
  110.             value = true to check, false to uncheck.
  111. ----------------------------------------------------------------------------*/
  112.  
  113. void DlgSetCheck (DialogPtr dlg, short item, Boolean value)
  114. {
  115.     Handle itemHandle;
  116.     short itemType;
  117.     Rect box;
  118.     
  119.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  120.     SetControlValue((ControlHandle)itemHandle, value);
  121. }
  122.  
  123.  
  124.  
  125. /*----------------------------------------------------------------------------
  126.     DlgToggleCheck 
  127.     
  128.     Toggle the state of a checkbox in a dialog.
  129.     
  130.     Entry:    dlg = pointer to dialog.
  131.             item = item number of checkbox control.
  132.  
  133. ----------------------------------------------------------------------------*/
  134.  
  135. void DlgToggleCheck (DialogPtr dlg, short item)
  136. {
  137.     Handle itemHandle;
  138.     short itemType;
  139.     Rect box;
  140.     short value;
  141.     
  142.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  143.     value = (GetControlValue((ControlHandle)itemHandle) == 1) ? 0 : 1;
  144.     SetControlValue((ControlHandle)itemHandle,value);
  145. }
  146.  
  147.  
  148.  
  149. /*----------------------------------------------------------------------------
  150.     DlgGetControl
  151.     
  152.     Get the control handle for a dialog item.
  153.     
  154.     Entry:    dlg = pointer to dialog.
  155.             item = item number of control item.
  156.             
  157.     Exit:    function result = handle to control.
  158. ----------------------------------------------------------------------------*/
  159.  
  160. ControlHandle DlgGetControl (DialogPtr dlg, short item)
  161. {
  162.     Handle itemHandle;
  163.     short itemType;
  164.     Rect box;
  165.  
  166.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  167.     return (ControlHandle)itemHandle;
  168. }
  169.  
  170.  
  171.  
  172. /*----------------------------------------------------------------------------
  173.     DlgGetCtlValue 
  174.     
  175.     Get the value of a control in a dialog.
  176.     
  177.     Entry:    dlg = pointer to dialog.
  178.             item = item number of control.
  179.             
  180.     Exit:    function result = value of control.
  181. ----------------------------------------------------------------------------*/
  182.  
  183. short DlgGetCtlValue (DialogPtr dlg, short item)
  184. {
  185.     Handle itemHandle;
  186.     short itemType;
  187.     Rect box;
  188.     
  189.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  190.     return GetControlValue((ControlHandle)itemHandle);
  191. }
  192.  
  193.  
  194.  
  195. /*----------------------------------------------------------------------------
  196.     DlgSetCtlValue 
  197.     
  198.     Set the value of a control in a dialog.
  199.     
  200.     Entry:    dlg = pointer to dialog.
  201.             item = item number of checkbox control.
  202.             value = new control value.
  203. ----------------------------------------------------------------------------*/
  204.  
  205. void DlgSetCtlValue (DialogPtr dlg, short item, short value)
  206. {
  207.     Handle itemHandle;
  208.     short itemType;
  209.     Rect box;
  210.     
  211.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  212.     SetControlValue((ControlHandle)itemHandle, value);
  213. }
  214.  
  215.  
  216.  
  217. /*----------------------------------------------------------------------------
  218.     DlgGetNumber 
  219.     
  220.     Get the value of a numeric dialog item.
  221.     
  222.     Entry:    dlg = pointer to dialog.
  223.             item = item number.
  224.             
  225.     Exit:    function result = numeric value of item.
  226. ----------------------------------------------------------------------------*/
  227.  
  228. long DlgGetNumber (DialogPtr dlg, short item)
  229. {
  230.     Handle itemHandle;
  231.     short itemType;
  232.     Rect box;
  233.     Str255 valStr;
  234.     long value;
  235.     
  236.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  237.     GetDialogItemText(itemHandle, valStr);
  238.     StringToNum(valStr, &value);
  239.     return value;
  240. }
  241.  
  242.  
  243.  
  244. /*----------------------------------------------------------------------------
  245.     DlgSetNumber 
  246.     
  247.     Set the value of a numeric dialog item.
  248.     
  249.     Entry:    dlg = pointer to dialog.
  250.             item = item number.
  251.             value = new value for item.
  252. ----------------------------------------------------------------------------*/
  253.  
  254. void DlgSetNumber (DialogPtr dlg, short item, long value)
  255. {
  256.     Handle itemHandle;
  257.     short itemType;
  258.     Rect box;
  259.     Str255 valStr;
  260.     
  261.     NumToString(value, valStr);
  262.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  263.     SetDialogItemText(itemHandle, valStr);
  264. }
  265.  
  266.  
  267.  
  268. /*----------------------------------------------------------------------------
  269.     DlgGetCString 
  270.     
  271.     Get the value of a string dialog item.
  272.     
  273.     Entry:    dlg = pointer to dialog.
  274.             item = item number.
  275.             
  276.     Exit:    value = the string (C format).
  277. ----------------------------------------------------------------------------*/
  278.  
  279. void DlgGetCString (DialogPtr dlg, short item, char *value)
  280. {
  281.     Handle itemHandle;
  282.     short itemType;
  283.     Rect box;
  284.     
  285.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  286.     GetDialogItemText(itemHandle, (StringPtr)value);
  287.     p2cstr((StringPtr)value);
  288. }
  289.  
  290.  
  291.  
  292. /*----------------------------------------------------------------------------
  293.     DlgSetCString 
  294.     
  295.     Set the value of a string dialog item.
  296.     
  297.     Entry:    dlg = pointer to dialog.
  298.             item = item number.
  299.             value = new string value (C format).
  300. ----------------------------------------------------------------------------*/
  301.  
  302. void DlgSetCString (DialogPtr dlg, short item, char *value)
  303. {
  304.     Handle itemHandle;
  305.     short itemType;
  306.     Rect box;
  307.     
  308.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  309.     c2pstr(value);
  310.     SetDialogItemText(itemHandle, (StringPtr)value);
  311.     p2cstr((StringPtr)value);
  312. }
  313.  
  314.  
  315.  
  316. /*----------------------------------------------------------------------------
  317.     DlgGetPString
  318.     
  319.     Get the value of a string dialog item.
  320.     
  321.     Entry:    dlg = pointer to dialog.
  322.             item = item number.
  323.             
  324.     Exit:    value = the string (Pascal format).
  325. ----------------------------------------------------------------------------*/
  326.  
  327. void DlgGetPString (DialogPtr dlg, short item, StringPtr value)
  328. {
  329.     Handle itemHandle;
  330.     short itemType;
  331.     Rect box;
  332.  
  333.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  334.     GetDialogItemText(itemHandle, value);
  335. }
  336.  
  337.  
  338.  
  339. /*----------------------------------------------------------------------------
  340.     DlgSetPString
  341.     
  342.     Set the value of a string dialog item.
  343.     
  344.     Entry:    dlg = pointer to dialog.
  345.             item = item number.
  346.             value = new string value (Pascal format).
  347. ----------------------------------------------------------------------------*/
  348.  
  349. void DlgSetPString (DialogPtr dlg, short item, StringPtr value)
  350. {
  351.     Handle itemHandle;
  352.     short itemType;
  353.     Rect box;
  354.  
  355.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  356.     SetDialogItemText(itemHandle, value);
  357. }
  358.  
  359.  
  360.  
  361. /*----------------------------------------------------------------------------
  362.     DlgSetScrollingText
  363.     
  364.     Set the value of a scrolling text field dialog item.
  365.     
  366.     Entry:    dlg = pointer to dialog.
  367.             item = item number.
  368.             value = pointer to first char of string.
  369.             len = length of string.
  370. ----------------------------------------------------------------------------*/
  371.  
  372. void DlgSetScrollingText (DialogPtr dlg, short item, char *value, short len)
  373. {
  374.     TWindow **info;
  375.     TDialogItemInfo **itemInfo;
  376.     TEHandle theTE;
  377.     ControlHandle vScroll;
  378.     
  379.     info = (TWindow**)GetWRefCon(dlg);
  380.     itemInfo = (**info).itemInfo;
  381.     theTE = (*itemInfo)[item-1].theTE;
  382.     vScroll = (*itemInfo)[item-1].vScroll;
  383.     TESetText(value, len, theTE);
  384.     TEScrollScrollSelectionIntoView(theTE, vScroll);
  385. }
  386.  
  387.  
  388.  
  389. /*----------------------------------------------------------------------------
  390.     DlgGetScrollingText
  391.     
  392.     Get the value of a scrolling text field dialog item.
  393.     
  394.     Entry:    dlg = pointer to dialog.
  395.             item = item number.
  396.             value = pointer to return buffer.
  397.             
  398.     Exit:    *len = length of returned value.
  399. ----------------------------------------------------------------------------*/
  400.  
  401. void DlgGetScrollingText (DialogPtr dlg, short item, char *value, short *len)
  402. {
  403.     TWindow **info;
  404.     TDialogItemInfo **itemInfo;
  405.     TEHandle theTE;
  406.     Handle text;
  407.     short teLen;
  408.     
  409.     info = (TWindow**)GetWRefCon(dlg);
  410.     itemInfo = (**info).itemInfo;
  411.     theTE = (*itemInfo)[item-1].theTE;
  412.     text = (**theTE).hText;
  413.     teLen = (**theTE).teLength;
  414.     BlockMoveData(*text, value, teLen);
  415.     *len = teLen;
  416. }
  417.  
  418.  
  419.  
  420. /*----------------------------------------------------------------------------
  421.     DlgSetScrollingTextSelection
  422.     
  423.     Set the selection range for a scrolling text field dialog item and make
  424.     this field the currently active one.
  425.     
  426.     Entry:    dlg = pointer to dialog.
  427.             item = item number.
  428.             selStart = start of selection range.
  429.             selEnd = end of selection range.
  430. ----------------------------------------------------------------------------*/
  431.  
  432. void DlgSetScrollingTextSelection (DialogPtr dlg, short item, 
  433.     short selStart, short selEnd)
  434. {
  435.     DialogPeek dPeek;
  436.     TWindow **info;
  437.     TDialogItemInfo **itemInfo;
  438.     short curItem, editField = 0;
  439.     TEHandle theTE, newTE;
  440.     ControlHandle vScroll;
  441.     
  442.     dPeek = (DialogPeek)dlg;
  443.     info = (TWindow**)GetWRefCon(dlg);
  444.     itemInfo = (**info).itemInfo;
  445.     curItem = (**info).curItem;
  446.     editField = dPeek->editField;
  447.     if (curItem > 0) {
  448.         theTE = (*itemInfo)[curItem-1].theTE;
  449.     } else if (editField >= 0) {
  450.         theTE = dPeek->textH;
  451.     } else {
  452.         theTE = nil;
  453.     }
  454.     if (theTE != nil) {
  455.         TESetSelect(0, 0, theTE);
  456.         TEDeactivate(theTE);
  457.     }
  458.     newTE = (*itemInfo)[item-1].theTE;
  459.     vScroll = (*itemInfo)[item-1].vScroll;
  460.     TEActivate(newTE);
  461.     TESetSelect(selStart, selEnd, newTE);
  462.     TEScrollScrollSelectionIntoView(newTE, vScroll);
  463.     (**info).curItem = item;
  464. }
  465.  
  466.  
  467.  
  468. /*----------------------------------------------------------------------------
  469.     DlgEnableItem
  470.     
  471.     Enable or disable an item in a dialog box. Checks to see if the item 
  472.     is a control and calls HiliteControl if so. Also redraws the outline 
  473.     around the default button if it's what's being enabled or disabled.
  474.     
  475.     Entry:    dlg = pointer to dialog.
  476.             item = item number of checkbox control.
  477.             enabled = new enabled state.
  478. ----------------------------------------------------------------------------*/
  479.  
  480. void DlgEnableItem (DialogPtr dlg, short item, Boolean enabled)
  481. {
  482.     TWindow **info;
  483.     Handle itemHandle;
  484.     short itemType;
  485.     Rect box;
  486.     Boolean    oldEnable;
  487.     GrafPtr port;
  488.  
  489.     GetPort(&port);
  490.     SetPort(dlg);
  491.     
  492.     info = (TWindow**)GetWRefCon(dlg);
  493.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  494.     oldEnable = (itemType & itemDisable) == 0;
  495.     itemType = enabled ? itemType & (~itemDisable) : itemType | itemDisable;
  496.     SetDialogItem(dlg, item, itemType, itemHandle, &box);
  497.     
  498.     if ((itemType & ctrlItem) != 0 && oldEnable != enabled) {
  499.         if (item == (**info).defaultItem) {
  500.             InsetRect(&box, -4, -4);
  501.             InvalRect(&box);
  502.         }
  503.         HiliteControl((ControlHandle)itemHandle, enabled ? 0 : 255);
  504.     }
  505.     
  506.     SetPort(port);
  507. }
  508.  
  509.  
  510.  
  511. /*----------------------------------------------------------------------------
  512.     DlgSetUserItem
  513.     
  514.     Set the procedure for a user item in a dialog.
  515.     
  516.     Entry:    dlg = pointer to dialog.
  517.             item = item number.
  518.             proc = universal pointer to user item proc.
  519. ----------------------------------------------------------------------------*/
  520.  
  521. void DlgSetUserItem (DialogPtr dlg, short item, UserItemUPP proc)
  522. {
  523.     Handle itemHandle;
  524.     short itemType;
  525.     Rect box;
  526.  
  527.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  528.     SetDialogItem(dlg, item, itemType, (Handle)proc, &box);
  529. }
  530.  
  531.  
  532.  
  533. /*----------------------------------------------------------------------------
  534.     DlgSetPict
  535.     
  536.     Set a dialog picture.
  537.     
  538.     Entry:    dlg = pointer to dialog.
  539.             item = item number of picture item.
  540.             pict = handle to picture.
  541. ----------------------------------------------------------------------------*/
  542.  
  543.  
  544. void DlgSetPict (DialogPtr dlg, short item, PicHandle pict)
  545. {
  546.     Handle itemHandle;
  547.     short itemType;
  548.     Rect box;
  549.     
  550.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  551.     SetDialogItem(dlg, item, itemType, (Handle)pict, &box);
  552. }
  553.  
  554.  
  555.  
  556. /*----------------------------------------------------------------------------
  557.     DlgGrayBorderItem
  558.     
  559.     A user item procedure to draw a gray border around itself.
  560.     
  561.     Entry:    dlg = pointer to dialog.
  562.             item = item number.
  563. ----------------------------------------------------------------------------*/
  564.  
  565. pascal void DlgGrayBorderItem (DialogPtr dlg, short item)
  566. {
  567.     Handle itemHandle;
  568.     short itemType;
  569.     Rect box;
  570.  
  571.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  572.     DrawGrayRect(&box);
  573. }
  574.  
  575.  
  576.  
  577. /*----------------------------------------------------------------------------
  578.     DlgDefaultButtonOutlineItem
  579.     
  580.     A user item procedure to outline the default button.
  581.     
  582.     Entry:    dlg = pointer to dialog.
  583.             item = item number.
  584. ----------------------------------------------------------------------------*/
  585.  
  586. static pascal void DlgDefaultButtonOutlineItem (DialogPtr dlg, short item)
  587. {
  588.     TWindow **info;
  589.     Handle itemHandle;
  590.     short itemType;
  591.     Rect box, r;
  592.     PenState savePen;
  593.     short defaultItem;
  594.     Boolean defaultOutline;
  595.  
  596.     info = (TWindow**)GetWRefCon(dlg);
  597.     defaultItem = (**info).defaultItem;
  598.     defaultOutline = (**info).defaultOutline;
  599.     if (defaultItem == 0 || !defaultOutline) return;
  600.     GetPenState(&savePen);
  601.     PenNormal();
  602.     PenSize(3, 3);
  603.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  604.     GetDialogItem(dlg, defaultItem, &itemType, &itemHandle, &r);
  605.     if ((itemType & itemDisable) != 0) {
  606.         DrawGrayRoundRect(&box, 16, 16);
  607.     } else {
  608.         FrameRoundRect(&box, 16, 16);
  609.     }
  610.     SetPenState(&savePen);
  611. }
  612.  
  613.  
  614.  
  615. /*----------------------------------------------------------------------------
  616.     DlgSetDefaultButtonOutline
  617.  
  618.     Set whether or not the default button is outlined.
  619.     
  620.     Entry:    dlg = pointer to dialog.
  621.             defaultOutline = true to outline default item.
  622. ----------------------------------------------------------------------------*/
  623.  
  624. void DlgSetDefaultButtonOutline (DialogPtr dlg, Boolean defaultOutline)
  625. {
  626.     TWindow **info;
  627.     short defaultItem;
  628.     short itemType;
  629.     Handle itemHandle;
  630.     Rect box;
  631.     
  632.     info = (TWindow**)GetWRefCon(dlg);
  633.     if ((**info).defaultOutline == defaultOutline) return;
  634.     (**info).defaultOutline = defaultOutline;
  635.     defaultItem = (**info).defaultItem;
  636.     GetDialogItem(dlg, defaultItem, &itemType, &itemHandle, &box);
  637.     InsetRect(&box, -4, -4);
  638.     EraseRect(&box);
  639.     InvalRect(&box);
  640. }
  641.  
  642.  
  643.  
  644. /*----------------------------------------------------------------------------
  645.     DlgFlashButton
  646.  
  647.     Flash a button.
  648.     
  649.     Entry:    dlg = pointer to dialog.
  650.             item = item number of button to flash.
  651. ----------------------------------------------------------------------------*/
  652.  
  653. void DlgFlashButton (DialogPtr dlg, short item)
  654. {
  655.     short itemType;
  656.     ControlHandle theItem;
  657.     Rect box;
  658.     long myticks;
  659.     
  660.     if (item > 0) {
  661.         GetDialogItem(dlg, item, &itemType, (Handle*)&theItem, &box);
  662.         HiliteControl(theItem, 1);
  663.         Delay(8, &myticks);
  664.         HiliteControl(theItem, 0);
  665.     }
  666. }
  667.  
  668.  
  669.  
  670. /*----------------------------------------------------------------------------
  671.     SetItemNumeric
  672.  
  673.     Set the "numeric" item info.
  674.     
  675.     Entry:    dlg = pointer to dialog.
  676.             item = item number of textedit field.
  677. ----------------------------------------------------------------------------*/
  678.  
  679. void SetItemNumeric (DialogPtr dlg, short item)
  680. {
  681.     TWindow **info;
  682.     TDialogItemInfo **itemInfo;
  683.     Boolean *validChars;
  684.     unsigned char c;
  685.     
  686.     info = (TWindow**)GetWRefCon(dlg);
  687.     itemInfo = (**info).itemInfo;
  688.     (*itemInfo)[item-1].numeric = true;
  689.     validChars = (*itemInfo)[item-1].validChars;
  690.     memset(validChars, false, 256);
  691.     for (c = '0'; c <= '9'; c++) validChars[c] = true;
  692. }
  693.  
  694.  
  695.  
  696. /*----------------------------------------------------------------------------
  697.     SetItemUSAsciiNoBlank
  698.  
  699.     Set the valid characters for an item to US ASCII but not a space.
  700.     
  701.     Entry:    dlg = pointer to dialog.
  702.             item = item number of textedit field.
  703. ----------------------------------------------------------------------------*/
  704.  
  705. void SetItemUSAsciiNoBlank (DialogPtr dlg, short item)
  706. {
  707.     TWindow **info;
  708.     TDialogItemInfo **itemInfo;
  709.     Boolean *validChars;
  710.     unsigned char c;
  711.     
  712.     info = (TWindow**)GetWRefCon(dlg);
  713.     itemInfo = (**info).itemInfo;
  714.     validChars = (*itemInfo)[item-1].validChars;
  715.     memset(validChars, false, 256);
  716.     for (c = 0x21; c <= 0x7e; c++) validChars[c] = true;
  717. }
  718.  
  719.  
  720.  
  721. /*----------------------------------------------------------------------------
  722.     SetItemURLSchemeName
  723.  
  724.     Set the valid characters for an item to alphanumerics, '+', '.', and
  725.     '-' (the characters legal in a URL scheme name).
  726.     
  727.     Entry:    dlg = pointer to dialog.
  728.             item = item number of textedit field.
  729. ----------------------------------------------------------------------------*/
  730.  
  731. void SetItemURLSchemeName (DialogPtr dlg, short item)
  732. {
  733.     TWindow **info;
  734.     TDialogItemInfo **itemInfo;
  735.     Boolean *validChars;
  736.     unsigned char c;
  737.     
  738.     info = (TWindow**)GetWRefCon(dlg);
  739.     itemInfo = (**info).itemInfo;
  740.     validChars = (*itemInfo)[item-1].validChars;
  741.     memset(validChars, false, 256);
  742.     for (c = 'a'; c <= 'z'; c++) validChars[c] = true;
  743.     for (c = 'A'; c <= 'Z'; c++) validChars[c] = true;
  744.     for (c = '0'; c <= '9'; c++) validChars[c] = true;
  745.     validChars['+'] = true;
  746.     validChars['-'] = true;
  747.     validChars['.'] = true;
  748. }
  749.  
  750.  
  751.  
  752. /*----------------------------------------------------------------------------
  753.     SetItemHostAddress
  754.  
  755.     Set the valid characters for an item to just the characters legal in
  756.     a host address.
  757.     
  758.     Entry:    dlg = pointer to dialog.
  759.             item = item number of textedit field.
  760. ----------------------------------------------------------------------------*/
  761.  
  762. void SetItemHostAddress (DialogPtr dlg, short item)
  763. {
  764.     TWindow **info;
  765.     TDialogItemInfo **itemInfo;
  766.     Boolean *validChars;
  767.     unsigned char c;
  768.     
  769.     info = (TWindow**)GetWRefCon(dlg);
  770.     itemInfo = (**info).itemInfo;
  771.     validChars = (*itemInfo)[item-1].validChars;
  772.     memset(validChars, false, 256);
  773.     for (c = 'A'; c <= 'Z'; c++) validChars[c] = true;
  774.     for (c = 'a'; c <= 'z'; c++) validChars[c] = true;
  775.     for (c = '0'; c <= '9'; c++) validChars[c] = true;
  776.     validChars['.'] = true;
  777.     validChars['-'] = true;
  778.     validChars['_'] = true;
  779.     validChars[','] = true;
  780.     validChars[':'] = true;
  781.     validChars[' '] = true;
  782. }
  783.  
  784.  
  785.  
  786. /*----------------------------------------------------------------------------
  787.     SetItemKeyword
  788.  
  789.     Set the valid characters for an item to just the characters legal in
  790.     a header keyword.
  791.     
  792.     Entry:    dlg = pointer to dialog.
  793.             item = item number of textedit field.
  794. ----------------------------------------------------------------------------*/
  795.  
  796. void SetItemKeyword (DialogPtr dlg, short item)
  797. {
  798.     TWindow **info;
  799.     TDialogItemInfo **itemInfo;
  800.     Boolean *validChars;
  801.     
  802.     SetItemUSAsciiNoBlank(dlg, item);
  803.     info = (TWindow**)GetWRefCon(dlg);
  804.     itemInfo = (**info).itemInfo;
  805.     validChars = (*itemInfo)[item-1].validChars;
  806.     validChars[':'] = false;
  807. }
  808.  
  809.  
  810.  
  811. /*----------------------------------------------------------------------------
  812.     SetItemPopupTypeinItem
  813.  
  814.     Set the "popupTypeinItem" item info.
  815.     
  816.     Entry:    dlg = pointer to dialog.
  817.             item = item number of popup menu control.
  818.             popupTypeInItem = item number of corresponding typein textedit
  819.                 field, or 0 if none.
  820. ----------------------------------------------------------------------------*/
  821.  
  822. void SetItemPopupTypeinItem (DialogPtr dlg, short item, short popupTypeinItem)
  823. {
  824.     TWindow **info;
  825.     TDialogItemInfo **itemInfo;
  826.     
  827.     info = (TWindow**)GetWRefCon(dlg);
  828.     itemInfo = (**info).itemInfo;
  829.     (*itemInfo)[item-1].popupTypeinItem = popupTypeinItem;
  830. }
  831.  
  832.  
  833.  
  834. /*----------------------------------------------------------------------------
  835.     SetItemKeyEquivalent
  836.  
  837.     Set the "keyEquivalent" item info.
  838.     
  839.     Entry:    dlg = pointer to dialog.
  840.             item = item number of push button control.
  841.             keyEquivalent = keyboard equivalent for control, or 0 if none.
  842. ----------------------------------------------------------------------------*/
  843.  
  844. void SetItemKeyEquivalent (DialogPtr dlg, short item, char keyEquivalent)
  845. {
  846.     TWindow **info;
  847.     TDialogItemInfo **itemInfo;
  848.     
  849.     info = (TWindow**)GetWRefCon(dlg);
  850.     itemInfo = (**info).itemInfo;
  851.     (*itemInfo)[item-1].keyEquivalent = keyEquivalent;
  852. }
  853.  
  854.  
  855.  
  856. /*----------------------------------------------------------------------------
  857.     SetItemMaxLength
  858.  
  859.     Set the "max length" item info.
  860.     
  861.     Entry:    dlg = pointer to dialog.
  862.             item = item number of textedit field.
  863.             maxLength = max length of field.
  864. ----------------------------------------------------------------------------*/
  865.  
  866. void SetItemMaxLength (DialogPtr dlg, short item, short maxLength)
  867. {
  868.     TWindow **info;
  869.     TDialogItemInfo **itemInfo;
  870.     
  871.     info = (TWindow**)GetWRefCon(dlg);
  872.     itemInfo = (**info).itemInfo;
  873.     (*itemInfo)[item-1].maxLength = maxLength;
  874. }
  875.  
  876.  
  877.  
  878. /*----------------------------------------------------------------------------
  879.     SetItemPassword
  880.  
  881.     Set the "password" item info.
  882.     
  883.     Entry:    dlg = pointer to dialog.
  884.             item = item number of textedit field.
  885.             password = pointer to password string, or nil if none.
  886. ----------------------------------------------------------------------------*/
  887.  
  888. void SetItemPassword (DialogPtr dlg, short item, char *password)
  889. {
  890.     TWindow **info;
  891.     TDialogItemInfo **itemInfo;
  892.     
  893.     info = (TWindow**)GetWRefCon(dlg);
  894.     itemInfo = (**info).itemInfo;
  895.     (*itemInfo)[item-1].password = password;
  896. }
  897.  
  898.  
  899.  
  900. /*----------------------------------------------------------------------------
  901.     ScrollingTextFieldUserItem
  902.     
  903.     The user item procedure to draw a scrolling text field.
  904.     
  905.     Entry:    dlg = pointer to dialog.
  906.             item = item number.
  907. ----------------------------------------------------------------------------*/
  908.  
  909. static pascal void ScrollingTextFieldUserItem (DialogPtr dlg, short item)
  910. {
  911.     TWindow **info;
  912.     TDialogItemInfo **itemInfo;
  913.     Handle itemHandle;
  914.     short itemType;
  915.     Rect box;
  916.     PenState savePen;
  917.     
  918.     info = (TWindow**)GetWRefCon(dlg);
  919.     itemInfo = (**info).itemInfo;
  920.  
  921.     GetDialogItem(dlg, item, &itemType, &itemHandle, &box);
  922.     GetPenState(&savePen);
  923.     PenNormal();
  924.     PenPat(&qd.black);
  925.     FrameRect(&box);
  926.     SetPenState(&savePen);
  927.     
  928.     TEUpdate(&dlg->portRect, (*itemInfo)[item-1].theTE);
  929. }
  930.  
  931.  
  932.  
  933. /*----------------------------------------------------------------------------
  934.     AutoScroll 
  935.     
  936.     Handle scrolling text field autoscrolling.
  937.             
  938.     Exit:    function result = true
  939. ----------------------------------------------------------------------------*/
  940.  
  941. static pascal Boolean AutoScroll (void)
  942. {
  943.     WindowPtr wind;
  944.     TWindow **info;
  945.     short curItem;
  946.     TDialogItemInfo **itemInfo;
  947.     TDialogItemInfo *pItemInfo;
  948.     ControlHandle vScroll;
  949.     TEHandle theTE;
  950.  
  951.     wind = MyFrontWindow();
  952.     if (wind == nil) return true;
  953.     info = (TWindow**)GetWRefCon(wind);
  954.     curItem = (**info).curItem;
  955.     if (curItem == 0) return true;
  956.     itemInfo = (**info).itemInfo;
  957.     pItemInfo = &(*itemInfo)[curItem-1];
  958.     vScroll = pItemInfo->vScroll;
  959.     theTE = pItemInfo->theTE;
  960.     TEScrollAutoScroll(theTE, vScroll);
  961.     return true;
  962. }
  963.  
  964.  
  965.  
  966. /*----------------------------------------------------------------------------
  967.     SetItemScrollingTextField
  968.  
  969.     Set a scrolling text field item.
  970.     
  971.     Entry:    dlg = pointer to dialog.
  972.             item = item number of field.
  973.             fontName = font name for field.
  974.             fontSize = font size for field.
  975.             readOnly = true if field is read only.
  976. ----------------------------------------------------------------------------*/
  977.  
  978. void SetItemScrollingTextField (DialogPtr dlg, short item, 
  979.     StringPtr fontName, short fontSize, Boolean readOnly)
  980. {
  981.     TWindow **info;
  982.     TDialogItemInfo **itemInfo;
  983.     short itemType;
  984.     Handle itemHandle;
  985.     Rect itemRect, teRect, sbarRect;
  986.     TEHandle theTE;
  987.     TextStyle savedStyle;
  988.     FontInfo fontInfo;
  989.     short lineHeight, numLinesInBox, boxHeight;
  990.     ControlHandle vScroll;
  991.     short fontNum;
  992.     Boolean *validChars;
  993.     GrafPtr port;
  994.     
  995.     GetPort(&port);
  996.     SetPort(dlg);
  997.     
  998.     info = (TWindow**)GetWRefCon(dlg);
  999.     itemInfo = (**info).itemInfo;
  1000.     (*itemInfo)[item-1].readOnly = readOnly;
  1001.     DlgSetUserItem(dlg, item, gScrollingTextFieldUserItemUPP);
  1002.  
  1003.     GetDialogItem(dlg, item, &itemType, &itemHandle, &itemRect);
  1004.     
  1005.     GetFontNumber(fontName, &fontNum);
  1006.  
  1007.     GetPortTextStyle(&savedStyle);
  1008.     numLinesInBox = 0;
  1009.     while (numLinesInBox < 2) {
  1010.         TextFont(fontNum);
  1011.         TextSize(fontSize);
  1012.         GetFontInfo(&fontInfo);
  1013.         lineHeight = fontInfo.ascent+fontInfo.descent+fontInfo.leading;
  1014.         numLinesInBox = (itemRect.bottom - itemRect.top - 2*kTextMargin) / lineHeight;
  1015.         if (numLinesInBox < 2) {
  1016.             if (fontSize > 12) {
  1017.                 fontSize = 12;
  1018.             } else if (fontSize > 9) {
  1019.                 fontSize = 9;
  1020.             } else if (fontNum != applFont) {
  1021.                 fontNum = applFont;
  1022.                 fontSize = 9;
  1023.             } else {
  1024.                 fontSize--;
  1025.             }
  1026.         }
  1027.     }
  1028.     boxHeight = lineHeight * numLinesInBox + 2*kTextMargin;
  1029.     itemRect.bottom = itemRect.top + boxHeight;
  1030.     SetDialogItem(dlg, item, itemType, itemHandle, &itemRect);
  1031.     
  1032.     teRect = itemRect;
  1033.     teRect.right -= 16;
  1034.     InsetRect(&teRect, kTextMargin, kTextMargin);
  1035.     theTE = TENew(&teRect, &teRect);
  1036.     (**theTE).clickLoop = gAutoScrollUPP;
  1037.     (*itemInfo)[item-1].theTE = theTE;
  1038.     
  1039.     sbarRect = itemRect;
  1040.     sbarRect.left = sbarRect.right - 16;
  1041.     vScroll = NewControl(dlg, &sbarRect, "\p", true, 0, 0, 0, scrollBarProc, item);
  1042.     (*itemInfo)[item-1].vScroll = vScroll;
  1043.     
  1044.     validChars = (*itemInfo)[item-1].validChars;
  1045.     if (readOnly) {
  1046.         memset(validChars, false, 256);
  1047.     } else {
  1048.         (*itemInfo)[item-1].returnIsLegal = true;
  1049.     }
  1050.     
  1051.     SetPortTextStyle(&savedStyle);
  1052.     
  1053.     SetPort(port);
  1054. }
  1055.  
  1056.  
  1057.  
  1058. /*----------------------------------------------------------------------------
  1059.     NotifyUser 
  1060.     
  1061.     Notify user that NewsWatcher requires attention and wait for the
  1062.     user to bring NewsWatcher to the foreground.
  1063. ----------------------------------------------------------------------------*/
  1064.  
  1065. void NotifyUser (void)
  1066. {
  1067.     NMRec nRec;
  1068.     OSErr err = noErr;
  1069.     Boolean gotEvt;
  1070.     EventRecord ev;
  1071.  
  1072.     nRec.qType = nmType;
  1073.     nRec.nmMark = 1;
  1074.     err = GetIconSuite(&nRec.nmIcon, kNewsWatcherSmallIconID, svAllSmallData);
  1075.     if (err != noErr) nRec.nmIcon = nil;
  1076.     nRec.nmSound = nil;
  1077.     nRec.nmStr = nil;
  1078.     nRec.nmResp = nil;
  1079.     NMInstall(&nRec);
  1080.     while (gInBackground) {
  1081.         gotEvt = WaitNextEvent(everyEvent & ~highLevelEventMask, &ev, GetCaretTime(), nil);
  1082.         if (gotEvt) HandleEvent(&ev);
  1083.     }
  1084.     NMRemove(&nRec);
  1085.     MyDisposeHandle(nRec.nmIcon);
  1086. }
  1087.  
  1088.  
  1089.  
  1090. /*----------------------------------------------------------------------------
  1091.     AEIdleProc 
  1092.     
  1093.     Apple event idle proc for AEInteractWithUser call.
  1094. ----------------------------------------------------------------------------*/
  1095.  
  1096. static pascal Boolean AEIdleProc (EventRecord *ev, long *sleep, RgnHandle *mouseRgn)
  1097. {
  1098.     HandleEvent(ev);
  1099.     *sleep = GetCaretTime();
  1100.     *mouseRgn = nil;
  1101.     return false;
  1102. }
  1103.  
  1104.  
  1105.  
  1106. /*----------------------------------------------------------------------------
  1107.     MyAEInteractWithUser 
  1108.     
  1109.     Initiate user interaction during servicing of an Apple event.
  1110.     
  1111.     Exit:    function result = error code (errAENoUserInteraction if 
  1112.                 user interaction is not allowed).
  1113. ----------------------------------------------------------------------------*/
  1114.  
  1115. static OSErr MyAEInteractWithUser (void)
  1116. {
  1117.     NMRec nRec;
  1118.     OSErr err = noErr;
  1119.  
  1120.     nRec.qType = nmType;
  1121.     nRec.nmMark = 1;
  1122.     err = GetIconSuite(&nRec.nmIcon, kNewsWatcherSmallIconID, svAllSmallData);
  1123.     if (err != noErr) nRec.nmIcon = nil;
  1124.     nRec.nmSound = nil;
  1125.     nRec.nmStr = nil;
  1126.     nRec.nmResp = nil;
  1127.     err = AEInteractWithUser(kAEDefaultTimeout, &nRec, gAEIdleProcUPP);
  1128.     MyDisposeHandle(nRec.nmIcon);
  1129.     return err;
  1130. }
  1131.  
  1132.  
  1133.  
  1134. /*----------------------------------------------------------------------------
  1135.     PrepUserInteraction 
  1136.     
  1137.     Prepare for user interaction (presenting a dialog).
  1138.     
  1139.     Exit:    function result = error code (errAENoUserInteraction if we are
  1140.                 serving an Apple event and user interaction is not allowed).
  1141. ----------------------------------------------------------------------------*/
  1142.  
  1143. OSErr PrepUserInteraction (void)
  1144. {
  1145.     WindowPtr wind;
  1146.     OSErr err = noErr;
  1147.  
  1148.     wind = MyFrontWindow();
  1149.     if (GetMyWindowKind(wind) == kStatus) DoClose(wind);
  1150.     if (gAEServer) {
  1151.         err = MyAEInteractWithUser();
  1152.         if (err != noErr) return err;
  1153.     } else {
  1154.         if (gInBackground) NotifyUser();
  1155.     }
  1156.     SetCursor(&qd.arrow);
  1157.     HiliteMenu(0);
  1158.     gInDialog = true;
  1159.     return noErr;
  1160. }
  1161.  
  1162.  
  1163.  
  1164. /*----------------------------------------------------------------------------
  1165.     InitDefaultIteminfo 
  1166.     
  1167.     Initialize default item info.
  1168.     
  1169.     Entry:    x = pointer to item info.
  1170. ----------------------------------------------------------------------------*/
  1171.  
  1172. static void InitDefaultItemInfo (TDialogItemInfo *x)
  1173. {
  1174.     short c;
  1175.  
  1176.     x->numeric = false;
  1177.     x->returnIsLegal = false;
  1178.     x->popupTypeinItem = 0;
  1179.     x->keyEquivalent = 0;
  1180.     x->maxLength = 0x7fff;
  1181.     x->password = nil;
  1182.     x->readOnly = false;
  1183.     x->theTE = nil;
  1184.     x->vScroll = nil;
  1185.     for (c = 0; c <= 255; c++) x->validChars[c] = isPrintable(c);
  1186. }
  1187.  
  1188.  
  1189.  
  1190. /*----------------------------------------------------------------------------
  1191.     MyGetNewDialog 
  1192.     
  1193.     Get a new dialog and intialize the dialog information.
  1194.     
  1195.     Entry:    id = resource id of DLOG resource.
  1196.             defaultItem = item number of default button, or 0 if none.
  1197.             cancelItem = item number of cancel button, or 0 if none.
  1198.     
  1199.     Exit:    function result = error code.
  1200.             *theDialog = pointer to dialog record.
  1201. ----------------------------------------------------------------------------*/
  1202.  
  1203. OSErr MyGetNewDialog (short id, short defaultItem, short cancelItem, 
  1204.     DialogPtr *theDialog)
  1205. {
  1206.     DialogTemplate **template;
  1207.     Boolean movableModal;
  1208.     DialogPtr dlg = nil;
  1209.     TWindow **info = nil;
  1210.     TDialogItemInfo **itemInfo = nil;
  1211.     TDialogItemInfo x;
  1212.     short numItems, i;
  1213.     Handle outlineDitl;
  1214.     short itemType;
  1215.     Handle itemHandle;
  1216.     Rect itemRect, defaultRect;
  1217.     OSErr err = noErr;
  1218.     Boolean savedCriticalSeq;
  1219.  
  1220.     BeginCriticalMemorySequence(&savedCriticalSeq);
  1221.     err = MyGetResource('DLOG', id, &template);
  1222.     if (err != noErr) goto exit;
  1223.     movableModal = (**template).procID == movableDBoxProc;
  1224.     err = PrepUserInteraction();
  1225.     if (err != noErr) goto exit;
  1226.     dlg = GetNewDialog(id, nil, (WindowPtr)-1);
  1227.     if (defaultItem != 0) {
  1228.         err = MyGetResource('DITL', kDefaultButtonOutlineUserItemDitlID, &outlineDitl);
  1229.         if (err != noErr) goto exit;
  1230.         AppendDITL(dlg, outlineDitl, overlayDITL);
  1231.         numItems = CountDITL(dlg);
  1232.         GetDialogItem(dlg, defaultItem, &itemType, &itemHandle, &defaultRect);
  1233.         GetDialogItem(dlg, numItems, &itemType, &itemHandle, &itemRect);
  1234.         InsetRect(&defaultRect, -4, -4);
  1235.         SetDialogItem(dlg, numItems, itemType, 
  1236.             (Handle)gDlgDefaultButtonOutlineItemUPP, &defaultRect);
  1237.     }
  1238.     err = MyNewHandle(sizeof(TWindow), &info);
  1239.     if (err != noErr) goto exit;
  1240.     SetWRefCon(dlg, (long)info);
  1241.     numItems = CountDITL(dlg);
  1242.     err = MyNewHandle(numItems * sizeof(TDialogItemInfo), &itemInfo);
  1243.     if (err != noErr) goto exit;
  1244.     (**info).kind = kDialog;
  1245.     (**info).movableModal = movableModal;
  1246.     (**info).defaultItem = defaultItem;
  1247.     (**info).defaultOutline = true;
  1248.     (**info).cancelItem = cancelItem;
  1249.     (**info).curItem = 0;
  1250.     (**info).itemInfo = itemInfo;
  1251.     InitDefaultItemInfo(&x);
  1252.     for (i = 0; i < numItems; i++) (*itemInfo)[i] = x;
  1253.     SetMenusTo(movableModal ? kAppleOnlyAboutDisabled : kAppleAllDisabled, 0, 0, 0, 0, 0);
  1254.     HiliteMenu(0);
  1255.     *theDialog = dlg;
  1256.     gMyCurDialog = dlg;
  1257.     EndCriticalMemorySequence(savedCriticalSeq);
  1258.     return noErr;
  1259.     
  1260. exit:
  1261.  
  1262.     if (dlg != nil) DisposeDialog(dlg);
  1263.     MyDisposeHandle(info);
  1264.     MyDisposeHandle(itemInfo);
  1265.     EndCriticalMemorySequence(savedCriticalSeq);
  1266.     gMyCurDialog = nil;
  1267.     return err;
  1268. }
  1269.  
  1270.  
  1271.  
  1272. /*----------------------------------------------------------------------------
  1273.     MyShortenDITL
  1274.     
  1275.     Shorten a dialog's item list.
  1276.     
  1277.     Entry:    dlg = pointer to dialog.
  1278.             numberItems = number of items to remove from the dialog item list.
  1279. ----------------------------------------------------------------------------*/
  1280.  
  1281. void MyShortenDITL (DialogPtr dlg, short numberItems)
  1282. {
  1283.     TWindow **info;
  1284.     TDialogItemInfo **itemInfo;
  1285.     TDialogItemInfo *pItemInfo;
  1286.     short numItems, item;
  1287.     char state;
  1288.     
  1289.     info = (TWindow**)GetWRefCon(dlg);
  1290.     itemInfo = (**info).itemInfo;
  1291.     numItems = CountDITL(dlg);
  1292.     state = MyHGetState(itemInfo);
  1293.     MyHLock(itemInfo);
  1294.     for (item = numItems - numberItems + 1, pItemInfo = *itemInfo + item - 1; 
  1295.         item <= numItems; 
  1296.         item++, pItemInfo++) 
  1297.     {
  1298.         if (pItemInfo->theTE != nil) TEDispose(pItemInfo->theTE);
  1299.         if (pItemInfo->vScroll != nil) DisposeControl(pItemInfo->vScroll);
  1300.     }
  1301.     MyHSetState(itemInfo, state);
  1302.     ShortenDITL(dlg, numberItems);
  1303.     numItems = CountDITL(dlg);
  1304.     if ((**info).curItem > numItems) (**info).curItem = 0;
  1305.     MySetHandleSize(itemInfo, numItems*sizeof(TDialogItemInfo));
  1306. }
  1307.  
  1308.  
  1309.  
  1310. /*----------------------------------------------------------------------------
  1311.     MyAppendDITL 
  1312.     
  1313.     Add items to a dialog's item list.
  1314.     
  1315.     Entry:    dlg = pointer to dialog.
  1316.             theDITL = handle to item list to append.
  1317.             theMethod = the manner in which the new items should be displayed,
  1318.                 as in the Dialog Manger AppendDITL procedure.
  1319.                 
  1320.     Exit:    function result = error code.
  1321. ----------------------------------------------------------------------------*/
  1322.  
  1323. OSErr MyAppendDITL (DialogPtr dlg, Handle theDITL, DITLMethod theMethod)
  1324. {
  1325.     TWindow **info;
  1326.     TDialogItemInfo **itemInfo;
  1327.     TDialogItemInfo x;
  1328.     short oldNumItems, numItems, i;
  1329.     OSErr err = noErr;
  1330.  
  1331.     oldNumItems = CountDITL(dlg);
  1332.     AppendDITL(dlg, theDITL, theMethod);
  1333.     info = (TWindow**)GetWRefCon(dlg);
  1334.     itemInfo = (**info).itemInfo;
  1335.     numItems = CountDITL(dlg);
  1336.     err = MySetHandleSizeCritical(itemInfo, numItems*sizeof(TDialogItemInfo));
  1337.     if (err != noErr) return err;
  1338.     InitDefaultItemInfo(&x);
  1339.     for (i = oldNumItems; i < numItems; i++) (*itemInfo)[i] = x;
  1340.     return noErr;
  1341. }
  1342.  
  1343.  
  1344.  
  1345. /*----------------------------------------------------------------------------
  1346.     ScrollAction 
  1347.     
  1348.     Vertical scroll bar action proc.
  1349.  
  1350.     Entry:    vScroll = handle to vertical scroll bar control.
  1351.             part = part code.
  1352. ----------------------------------------------------------------------------*/
  1353.  
  1354. static pascal void ScrollAction (ControlHandle vScroll, short part)
  1355. {
  1356.     WindowPtr wind;
  1357.     TWindow **info;
  1358.     TDialogItemInfo **itemInfo;
  1359.     short item;
  1360.     TEHandle theTE;
  1361.     
  1362.     wind = (**vScroll).contrlOwner;
  1363.     info = (TWindow**)GetWRefCon(wind);
  1364.     itemInfo = (**info).itemInfo;
  1365.     item = GetControlReference(vScroll);
  1366.     theTE = (*itemInfo)[item-1].theTE;
  1367.     SetControlReference(vScroll, 0);
  1368.     TEScrollScrollByPartCode(theTE, vScroll, part);
  1369.     SetControlReference(vScroll, item);
  1370. }
  1371.  
  1372.  
  1373.  
  1374. /*----------------------------------------------------------------------------
  1375.     DialogFilter 
  1376.     
  1377.     Universal modal dialog filter.
  1378.         
  1379.     Entry:    dlg = pointer to dialog.
  1380.             ev = pointer to event record.
  1381.             
  1382.     Exit:    function result = true if event handled and item hit.
  1383.             *itemHit = item number of item hit.
  1384.             ev = pointer to possibly modified event record.
  1385. ----------------------------------------------------------------------------*/
  1386.  
  1387. pascal Boolean DialogFilter (DialogPtr dlg, EventRecord *ev, short *itemHit)
  1388. {
  1389.     static RgnHandle cursorRgn = nil;
  1390.     short itemType;
  1391.     Handle itemHandle;
  1392.     Rect box;
  1393.     
  1394.     if (ev->what != nullEvent) {
  1395.         gPrevEvent = gCurEvent;
  1396.         gCurEvent = *ev;
  1397.     }
  1398.     
  1399.     if (cursorRgn == nil) cursorRgn = NewRgn();
  1400.     HandleIdle(cursorRgn);
  1401.  
  1402.     gHandled = false;
  1403.     gItem = 0;
  1404.     gEv = ev;
  1405.     
  1406.     if (ev->what == updateEvt && (WindowPtr)ev->message == dlg) return false;
  1407.     if (ev->what == updateEvt || ev->what == activateEvt) gHandled = true;
  1408.     
  1409.     HandleEvent(ev);
  1410.     
  1411.     if (gItem != 0) {
  1412.         GetDialogItem(dlg, gItem, &itemType, &itemHandle, &box);
  1413.         if ((itemType & itemDisable) != 0) {
  1414.             ev->what = nullEvent;
  1415.             return false;
  1416.         } else {
  1417.             *itemHit = gItem;
  1418.             return true;
  1419.         }
  1420.     } else if (gHandled) {
  1421.         ev->what = nullEvent;
  1422.         return false;
  1423.     } else {
  1424.         return false;
  1425.     }
  1426. }
  1427.  
  1428.  
  1429.  
  1430. /*----------------------------------------------------------------------------
  1431.     MyModalDialog 
  1432.  
  1433.     Present a modal dialog.
  1434.     
  1435.     Entry:    dlg = pointer to dialog window.
  1436.             filterProc = filter proc UPP.
  1437.             
  1438.     Exit:    *itemHit = item number hit.
  1439. ----------------------------------------------------------------------------*/
  1440.  
  1441. void MyModalDialog (DialogPtr dlg, ModalFilterUPP filterProc, short *itemHit)
  1442. {
  1443.     MyShowWindow(dlg);
  1444.     ModalDialog(filterProc, itemHit);
  1445. }
  1446.  
  1447.  
  1448.  
  1449. /*----------------------------------------------------------------------------
  1450.     MyMovableModalDialog 
  1451.  
  1452.     Present a movable modal dialog.
  1453.     
  1454.     Entry:    dlg = pointer to dialog window.
  1455.             filterProc = filter proc UPP.
  1456.             
  1457.     Exit:    *itemHit = item number hit.
  1458. ----------------------------------------------------------------------------*/
  1459.  
  1460. void MyMovableModalDialog (DialogPtr dlg, ModalFilterProcPtr filterProc, short *itemHit)
  1461. {
  1462.     EventRecord ev;
  1463.     Boolean gotEvt;
  1464.     DialogPtr tempDlg;
  1465.     GrafPtr port;
  1466.     
  1467.     GetPort(&port);
  1468.     SetPort(dlg);
  1469.  
  1470.     MyShowWindow(dlg);
  1471.  
  1472.     while (true) {
  1473.         gotEvt = WaitNextEvent(everyEvent & ~highLevelEventMask, &ev, 0, nil);
  1474.         if (!gotEvt) ev.what = nullEvent;
  1475.         if ((*filterProc)(dlg, &ev, itemHit)) goto exit;
  1476.         if (!gHandled && IsDialogEvent(&ev) && 
  1477.             DialogSelect(&ev, &tempDlg, itemHit)) goto exit;
  1478.     }
  1479.         
  1480. exit:
  1481.  
  1482.     SetPort(port);
  1483.     
  1484. }
  1485.  
  1486.  
  1487.  
  1488. /*----------------------------------------------------------------------------
  1489.     ErrorMessage 
  1490.     
  1491.     Issue an error message alert.
  1492.     
  1493.     Entry:    msg = error message.
  1494. ----------------------------------------------------------------------------*/
  1495.  
  1496. void ErrorMessage (char *msg)
  1497. {
  1498.     DialogPtr dlg;
  1499.     short item;
  1500.     OSErr err = noErr;
  1501.  
  1502.     c2pstr(msg);
  1503.     ParamText((StringPtr)msg, "\p", "\p", "\p");
  1504.     p2cstr((StringPtr)msg);
  1505.     err = MyGetNewDialog(kErrDlg, ok, 0, &dlg);
  1506.     SysBeep(0);
  1507.     if (err != noErr) return;
  1508.     MyModalDialog(dlg, gDialogFilterUPP, &item);
  1509.     DoClose(dlg);
  1510. }
  1511.  
  1512.  
  1513.  
  1514. /*----------------------------------------------------------------------------
  1515.     ErrorMessageNumber 
  1516.     
  1517.     Issue an error message alert.
  1518.     
  1519.     Entry:    index = index in STR# 128 resource of error message.
  1520. ----------------------------------------------------------------------------*/
  1521.  
  1522. void ErrorMessageNumber (short index)
  1523. {
  1524.     CStr255 msg;
  1525.     
  1526.     GetCString(index, msg);
  1527.     ErrorMessage(msg);
  1528. }
  1529.  
  1530.  
  1531.  
  1532. /*----------------------------------------------------------------------------
  1533.     NoteMessage 
  1534.     
  1535.     Issue a note message alert.
  1536.     
  1537.     Entry:    msg = note message.
  1538. ----------------------------------------------------------------------------*/
  1539.  
  1540. void NoteMessage (char *msg)
  1541. {
  1542.     DialogPtr dlg;
  1543.     short item;
  1544.     OSErr err;
  1545.  
  1546.     c2pstr(msg);
  1547.     ParamText((StringPtr)msg, "\p", "\p", "\p");
  1548.     p2cstr((StringPtr)msg);
  1549.     err = MyGetNewDialog(kNoteDlg, ok, 0, &dlg);
  1550.     SysBeep(0);
  1551.     if (err != noErr) return;
  1552.     MyModalDialog(dlg, gDialogFilterUPP, &item);
  1553.     DoClose(dlg);
  1554. }
  1555.  
  1556.  
  1557.  
  1558. /*----------------------------------------------------------------------------
  1559.     NoteMessageNumber 
  1560.     
  1561.     Issue a note message alert.
  1562.     
  1563.     Entry:    index = index in STR# 128 resource of note message.
  1564. ----------------------------------------------------------------------------*/
  1565.  
  1566. void NoteMessageNumber (short index)
  1567. {
  1568.     CStr255 msg;
  1569.     
  1570.     GetCString(index, msg);
  1571.     NoteMessage(msg);
  1572. }
  1573.  
  1574.  
  1575.  
  1576. /*----------------------------------------------------------------------------
  1577.     CautionMessage 
  1578.     
  1579.     Issue a caution message alert.
  1580.     
  1581.     Entry:    msg = caution message.
  1582. ----------------------------------------------------------------------------*/
  1583.  
  1584. void CautionMessage (char *msg)
  1585. {
  1586.     DialogPtr dlg;
  1587.     short item;
  1588.     OSErr err = noErr;
  1589.  
  1590.     c2pstr(msg);
  1591.     ParamText((StringPtr)msg, "\p", "\p", "\p");
  1592.     p2cstr((StringPtr)msg);
  1593.     err = MyGetNewDialog(kCautionDlg, ok, 0, &dlg);
  1594.     SysBeep(0);
  1595.     if (err != noErr) return;
  1596.     MyModalDialog(dlg, gDialogFilterUPP, &item);
  1597.     DoClose(dlg);
  1598. }
  1599.  
  1600.  
  1601.  
  1602. /*----------------------------------------------------------------------------
  1603.     CautionMessageNumber 
  1604.     
  1605.     Issue a caution message alert.
  1606.     
  1607.     Entry:    index = index in STR# 128 resource of caution message.
  1608. ----------------------------------------------------------------------------*/
  1609.  
  1610. void CautionMessageNumber (short index)
  1611. {
  1612.     CStr255 msg;
  1613.     
  1614.     GetCString(index, msg);
  1615.     CautionMessage(msg);
  1616. }
  1617.  
  1618.  
  1619.  
  1620. /*----------------------------------------------------------------------------
  1621.     StopAlertMessage 
  1622.     
  1623.     Issue an error message alert from a dialog.
  1624.     
  1625.     Entry:    msg = error message.
  1626. ----------------------------------------------------------------------------*/
  1627.  
  1628. void StopAlertMessage (char *msg)
  1629. {
  1630.     c2pstr(msg);
  1631.     ParamText((StringPtr)msg, "\p", "\p", "\p");
  1632.     p2cstr((StringPtr)msg);
  1633.     StopAlert(kErrAlert, nil);
  1634. }
  1635.  
  1636.  
  1637.  
  1638. /*----------------------------------------------------------------------------
  1639.     StopAlertNumber 
  1640.     
  1641.     Issue an error message alert from a dialog.
  1642.     
  1643.     Entry:    index = index in STR# 128 resource of error message.
  1644. ----------------------------------------------------------------------------*/
  1645.  
  1646. void StopAlertNumber (short index)
  1647. {
  1648.     CStr255 msg;
  1649.     
  1650.     GetCString(index, msg);
  1651.     StopAlertMessage(msg);
  1652. }
  1653.  
  1654.  
  1655.  
  1656. /*----------------------------------------------------------------------------
  1657.     CautionAlertMessage 
  1658.     
  1659.     Issue a caution message alert from a dialog.
  1660.     
  1661.     Entry:    msg = error message.
  1662. ----------------------------------------------------------------------------*/
  1663.  
  1664. void CautionAlertMessage (char *msg)
  1665. {
  1666.     c2pstr(msg);
  1667.     ParamText((StringPtr)msg, "\p", "\p", "\p");
  1668.     p2cstr((StringPtr)msg);
  1669.     CautionAlert(kErrAlert, nil);
  1670. }
  1671.  
  1672.  
  1673.  
  1674. /*----------------------------------------------------------------------------
  1675.     CautionAlertNumber 
  1676.     
  1677.     Issue a caution message alert from a dialog.
  1678.     
  1679.     Entry:    index = index in STR# 128 resource of error message.
  1680. ----------------------------------------------------------------------------*/
  1681.  
  1682. void CautionAlertNumber (short index)
  1683. {
  1684.     CStr255 msg;
  1685.     
  1686.     GetCString(index, msg);
  1687.     CautionAlertMessage(msg);
  1688. }
  1689.  
  1690.  
  1691.  
  1692. /*----------------------------------------------------------------------------
  1693.     ReportSystemError 
  1694.     
  1695.     Report a system error.
  1696.     
  1697.     Entry:    err = error number.
  1698. ----------------------------------------------------------------------------*/
  1699.  
  1700. void ReportSystemError (OSErr err)
  1701. {
  1702.     Str255 errNumStr;
  1703.     DialogPtr dlg;
  1704.     short item, id;
  1705.     Str255 serverType;
  1706.     
  1707.     switch (err) {
  1708.         case noErr:
  1709.         case userCanceledErr:
  1710.         case iPrAbort:
  1711.             return;
  1712.         case memFullErr:
  1713.             err = MyGetNewDialog(kOutOfMemoryDlg, ok, 0, &dlg);
  1714.             SysBeep(0);
  1715.             if (err != noErr) return;
  1716.             MyModalDialog(dlg, gDialogFilterUPP, &item);
  1717.             DoClose(dlg);
  1718.             return;
  1719.         case netOpenDriverErr:
  1720.             ErrorMessageNumber(NetHaveOT() ? kStrCouldNotOpenOT : 
  1721.                 kStrCouldNotOpenMacTCP);
  1722.             return;
  1723.         case netDNRErr:
  1724.         case netOpenStreamErr:
  1725.         case netLostConnectionErr:
  1726.             switch (err) {
  1727.                 case netDNRErr:
  1728.                     id = kDlgDNRErr;
  1729.                     break;
  1730.                 case netOpenStreamErr:
  1731.                     id = kDlgOpenStreamErr;
  1732.                     break;
  1733.                 case netLostConnectionErr:
  1734.                     id = kDlgLostConnectionErr;
  1735.                     break;
  1736.             }
  1737.             GetPString(gServerErrInfoType, serverType);
  1738.             c2pstr(gServerErrInfoHost);
  1739.             ParamText(serverType, (StringPtr)gServerErrInfoHost, "\p", "\p");
  1740.             err = MyGetNewDialog(id, ok, 0, &dlg);
  1741.             SysBeep(0);
  1742.             if (err != noErr) return;
  1743.             MyModalDialog(dlg, gDialogFilterUPP, &item);
  1744.             DoClose(dlg);
  1745.             return;
  1746.         case dirFulErr:
  1747.             ErrorMessageNumber(kStrDirFull);
  1748.             return;
  1749.         case dskFulErr:
  1750.             ErrorMessageNumber(kStrDiskFull);
  1751.             return;
  1752.         case ioErr:
  1753.             ErrorMessageNumber(kStrDiskIOErr);
  1754.             return;
  1755.         case opWrErr:
  1756.         case fLckdErr:
  1757.         case fBsyErr:
  1758.         case permErr:
  1759.         case wrPermErr:
  1760.             ErrorMessageNumber(kStrFileLockedOrBusy);
  1761.             return;
  1762.         case vLckdErr:
  1763.             ErrorMessageNumber(kStrVolLocked);
  1764.             return;
  1765.         case wPrErr:
  1766.             ErrorMessageNumber(kStrDiskWriteProtected);
  1767.             return;
  1768.         default:
  1769.             NumToString(err, errNumStr);
  1770.             ParamText(errNumStr, "\p", "\p", "\p");
  1771.             err = MyGetNewDialog(kUnexpectedErrDlg, ok, 0, &dlg);
  1772.             SysBeep(0);
  1773.             if (err != noErr) return;
  1774.             MyModalDialog(dlg, gDialogFilterUPP, &item);
  1775.             DoClose(dlg);
  1776.             return;
  1777.     }
  1778. }
  1779.  
  1780.  
  1781.  
  1782. /*----------------------------------------------------------------------------
  1783.   SaveNetErrorInfo 
  1784.   
  1785.   Save information for a network error message.
  1786.   
  1787.   Entry:    index = index in STR# of server type ("news", "mail", or "FTP").
  1788.               host = address of server host, as a C-format string.
  1789. ----------------------------------------------------------------------------*/
  1790.  
  1791. void SaveNetErrorInfo (short index, char *host)
  1792. {
  1793.     gServerErrInfoType = index;
  1794.     strcpy(gServerErrInfoHost, host);
  1795. }    
  1796.  
  1797.  
  1798.  
  1799. /*----------------------------------------------------------------------------
  1800.   ServerErrorMessage 
  1801.   
  1802.   Issue a server error message.
  1803.   
  1804.   Entry:    index = index in STR# of server type ("news", "mail", or "FTP").
  1805.               command = the command NewsWatcher tried to send to the server,
  1806.                   or nil if none (connect error).
  1807.               response = error message as returned by the server.
  1808.               
  1809.   Exit:        function result = error code.
  1810. ----------------------------------------------------------------------------*/
  1811.  
  1812. OSErr ServerErrorMessage (short index, char *command, char *response)
  1813. {
  1814.     CStr255 cmd, serverType;
  1815.     Handle msg = nil;
  1816.     Str255 errMsg;
  1817.     char *p;
  1818.     short len;
  1819.     DialogPtr dlg = nil;
  1820.     short item;
  1821.     OSErr err = noErr;
  1822.     
  1823.     MyICReadSharedPrefs(kICScreenFont);
  1824.     
  1825.     GetCString(index, serverType);
  1826.     
  1827.     if (command == nil) {
  1828.         strcpy(cmd, " ");
  1829.     } else if (MyStrNEqual(command, "PASS", 4)) {
  1830.         strcpy(cmd, "PASS *******");
  1831.     } else if (MyStrNEqual(command, "AUTHINFO PASS", 13)) {
  1832.         strcpy(cmd, "AUTHINFO PASS *******");
  1833.     } else {
  1834.         strcpy(cmd, command);
  1835.     }
  1836.     
  1837.     p = response;
  1838.     while (*p == ' ') p++;
  1839.     while (isdigit(*p)) p++;
  1840.     while (*p == ' ') p++;
  1841.     len = strlen(p);
  1842.     BlockMoveData(p, errMsg+1, len);
  1843.     *errMsg = len;
  1844.     
  1845.     if (*cmd == 0) {
  1846.         err = MyGetResource('TEXT', kServerConnectErrMessageText, &msg);
  1847.         if (err != noErr) goto exit;
  1848.         Munger(msg, 0, "^0", 2, serverType, strlen(serverType));
  1849.         Munger(msg, 0, "^1", 2, response, strlen(response));
  1850.     } else {
  1851.         err = MyGetResource('TEXT', kServerErrMessageText, &msg);
  1852.         if (err != noErr) goto exit;
  1853.         Munger(msg, 0, "^0", 2, serverType, strlen(serverType));
  1854.         Munger(msg, 0, "^1", 2, cmd, strlen(cmd));
  1855.         Munger(msg, 0, "^2", 2, response, strlen(response));
  1856.     }
  1857.  
  1858.     SysBeep(0);
  1859.     err = MyGetNewDialog(kServerErrDlg, ok, 0, &dlg);
  1860.     if (err != noErr) goto exit;
  1861.     RestoreMovableModalDialogPosition(dlg, gPrefs.servErrLoc);
  1862.     ParamText(errMsg, "\p", "\p", "\p");
  1863.     SetItemScrollingTextField(dlg, kServerErrScrollingTextItem,
  1864.         gPrefs.textFont, gPrefs.textSize, true);
  1865.     MyHLock(msg);
  1866.     DlgSetScrollingText(dlg, kServerErrScrollingTextItem, *msg,
  1867.         MyGetHandleSize(msg));
  1868.     MyReleaseResource(msg);
  1869.     DlgSetScrollingTextSelection(dlg, kServerErrScrollingTextItem, 0, 0);
  1870.     MyMovableModalDialog(dlg, DialogFilter, &item);
  1871.     SaveMovableModalDialogPosition(dlg, &gPrefs.servErrLoc);
  1872.     return DoClose(dlg);
  1873.     
  1874. exit:
  1875.  
  1876.     if (dlg != nil) DisposeDialog(dlg);
  1877.     if (msg != nil) MyReleaseResource(msg);
  1878.     return err;
  1879. }
  1880.  
  1881.  
  1882.  
  1883. /*----------------------------------------------------------------------------
  1884.     RestoreMovableModalDialogPosition 
  1885.     
  1886.     Restore the saved position of a movable modal dialog window.
  1887.             
  1888.     Entry:    dlg = pointer to dialog window.
  1889.             pos = saved position in global coordinates.
  1890. ----------------------------------------------------------------------------*/
  1891.  
  1892. void RestoreMovableModalDialogPosition (DialogPtr dlg, Point pos)
  1893. {
  1894.     GrafPtr port;
  1895.     Point defaultLocn;
  1896.     
  1897.     GetPort(&port);
  1898.     SetPort(dlg);
  1899.     if (pos.h != 0 || pos.v != 0) {
  1900.         SetPt(&defaultLocn, 0, 0);
  1901.         LocalToGlobal(&defaultLocn);
  1902.         MoveWindow(dlg, pos.h, pos.v, false);
  1903.         if (!WindOnScreen(dlg)) MoveWindow(dlg, defaultLocn.h, defaultLocn.v, false);
  1904.     }
  1905.     SetPort(port);
  1906. }
  1907.  
  1908.  
  1909.  
  1910. /*----------------------------------------------------------------------------
  1911.     SaveMovableModalDialogPosition 
  1912.     
  1913.     Save the position of a movable modal dialog window.
  1914.             
  1915.     Entry:    dlg = pointer to dialog window.
  1916.     
  1917.     Exit:    *pos = saved position in global coordinates.
  1918. ----------------------------------------------------------------------------*/
  1919.  
  1920. void SaveMovableModalDialogPosition (DialogPtr dlg, Point *pos)
  1921. {
  1922.     GrafPtr port;
  1923.     
  1924.     GetPort(&port);
  1925.     SetPort(dlg);
  1926.     SetPt(pos, 0, 0);
  1927.     LocalToGlobal(pos);
  1928.     SetPort(port);
  1929. }
  1930.  
  1931.  
  1932.  
  1933. /*----------------------------------------------------------------------------
  1934.     Activate 
  1935.     
  1936.     Handle an activate event for a dialog window.
  1937.             
  1938.     Entry:    wind = pointer to dialog window.
  1939.             act = true to activate, false to deactivate
  1940. ----------------------------------------------------------------------------*/
  1941.  
  1942. static void Activate (WindowPtr wind, Boolean act)
  1943. {
  1944.     DialogPeek dPeek;
  1945.     TWindow **info;
  1946.     TDialogItemInfo **itemInfo;
  1947.     TEHandle theTE;
  1948.     short curItem, editField = 0;
  1949.     
  1950.     dPeek = (DialogPeek)wind;
  1951.     info = (TWindow**)GetWRefCon(wind);
  1952.     itemInfo = (**info).itemInfo;
  1953.     curItem = (**info).curItem;
  1954.     if (curItem > 0) {
  1955.         editField = curItem;
  1956.         theTE = (*itemInfo)[curItem-1].theTE;
  1957.     } else {
  1958.         editField = dPeek->editField + 1;
  1959.         theTE = dPeek->textH;
  1960.     }
  1961.     if (editField > 0) {
  1962.         if (act) {
  1963.             TEActivate(theTE);
  1964.         } else {
  1965.             TEDeactivate(theTE);
  1966.         }
  1967.     }
  1968. }
  1969.  
  1970.  
  1971.  
  1972. /*----------------------------------------------------------------------------
  1973.     Update 
  1974.     
  1975.     Handle an update event for a dialog window.
  1976.             
  1977.     Entry:    wind = pointer to dialog window.
  1978. ----------------------------------------------------------------------------*/
  1979.  
  1980. static void Update (WindowPtr wind)
  1981. {
  1982.     UpdateDialog(wind, wind->visRgn);
  1983. }
  1984.  
  1985.  
  1986.  
  1987. /*----------------------------------------------------------------------------
  1988.     Mouse 
  1989.     
  1990.     Handle a mouse down event in the content area of a dialog window.
  1991.             
  1992.     Entry:    wind = pointer to dialog window.
  1993.             where = location of mouse down in local coords.
  1994.             modifiers = modifiers field from event record.
  1995.             
  1996.     Exit:    function result = error code.
  1997. ----------------------------------------------------------------------------*/
  1998.  
  1999. static OSErr Mouse (WindowPtr wind, Point where, short modifiers)
  2000. {
  2001.     DialogPeek dPeek;
  2002.     TWindow **info;
  2003.     TDialogItemInfo **itemInfo;
  2004.     TDialogItemInfo *pItemInfo;
  2005.     TEHandle theTE, curTE;
  2006.     ControlHandle vScroll, popupCtl, control;
  2007.     Str255 str;
  2008.     short item, popupTypeinItem, part, oldVal, dv;
  2009.     Boolean numeric;
  2010.     Rect box, viewRect;
  2011.     Handle itemHandle;
  2012.     short itemType, curItem;
  2013.     short selStart, selEnd, editField;
  2014.  
  2015.     dPeek = (DialogPeek)wind;
  2016.     info = (TWindow**)GetWRefCon(wind);
  2017.     itemInfo = (**info).itemInfo;
  2018.     curItem = (**info).curItem;
  2019.     if (curItem > 0) {
  2020.         editField = curItem;
  2021.         curTE = (*itemInfo)[curItem-1].theTE;
  2022.     } else if (dPeek->editField >= 0) {
  2023.         editField = dPeek->editField + 1;
  2024.         curTE = dPeek->textH;
  2025.     } else {
  2026.         curTE = nil;
  2027.     }
  2028.  
  2029.     item = FindDialogItem(wind, where) + 1;
  2030.     
  2031.     if (item <= 0) {
  2032.         gHandled = true;
  2033.         return noErr;
  2034.     }
  2035.     
  2036.     pItemInfo = &(*itemInfo)[item-1];
  2037.     popupTypeinItem = pItemInfo->popupTypeinItem;
  2038.     theTE = pItemInfo->theTE;
  2039.     vScroll = pItemInfo->vScroll;
  2040.     GetDialogItem(wind, item, &itemType, &itemHandle, &box);
  2041.     
  2042.     if (popupTypeinItem != 0) {
  2043.         if (curTE != nil) {
  2044.             selStart = (**curTE).selStart;
  2045.             selEnd = (**curTE).selEnd;
  2046.         }
  2047.         SelectDialogItemText(wind, popupTypeinItem, 0, 0x7fff);
  2048.         DlgGetPString(wind, popupTypeinItem, str);
  2049.         popupCtl = DlgGetControl(wind, item);
  2050.         numeric = (*itemInfo)[popupTypeinItem-1].numeric;
  2051.         if (TrackPopup(popupCtl, where, str, numeric)) {
  2052.             gItem = item;
  2053.             GetPopupPString(popupCtl, kCurrentPopupItem, str);
  2054.             DlgSetPString(wind, popupTypeinItem, str);
  2055.             if (curTE != nil) {
  2056.                 if (editField == popupTypeinItem) {
  2057.                     SelectDialogItemText(wind, popupTypeinItem, 0, 0x7fff);
  2058.                 } else if (curItem == 0) {
  2059.                     SelectDialogItemText(wind, editField, selStart, selEnd);
  2060.                 } else {
  2061.                     theTE = dPeek->textH;
  2062.                     TESetSelect(0, 0, theTE);
  2063.                     TEDeactivate(theTE);
  2064.                 }
  2065.             }    
  2066.         }
  2067.         gHandled = true;
  2068.         return noErr;
  2069.     }
  2070.     
  2071.     if (theTE != nil) {
  2072.         part = FindControl(where, wind, &control);
  2073.         viewRect = (**theTE).viewRect;
  2074.         if ((part != 0 && control == vScroll) || PtInRect(where, &viewRect)) {
  2075.             if (curItem != item) {
  2076.                 if (curTE != nil) {
  2077.                     TESetSelect(0, 0, curTE);
  2078.                     TEDeactivate(curTE);
  2079.                     if ((**curTE).teLength == 0) {
  2080.                         /* Goofy hack to erase insertion point when tabbing from an
  2081.                            empty field right after a window activate. Don't know why
  2082.                            this is required, but it is. */ 
  2083.                         box = (**curTE).viewRect;
  2084.                         EraseRect(&box);
  2085.                     }
  2086.                 }
  2087.                 TEActivate(theTE);
  2088.                 (**info).curItem = item;
  2089.             }
  2090.             if (part != 0) {
  2091.                 if (part == inThumb) {
  2092.                     oldVal = GetControlValue(vScroll);
  2093.                     TrackControl(vScroll, where, nil);
  2094.                     dv = GetControlValue(vScroll) - oldVal;
  2095.                     if (dv != 0) TEScrollScrollText(theTE, vScroll, -dv);
  2096.                 } else {
  2097.                     TrackControl(vScroll, where, gScrollActionUPP);
  2098.                     TEScrollAdjustScrollMax(theTE, vScroll);
  2099.                 }
  2100.             } else {
  2101.                 if (curItem == item) {
  2102.                     MyTEClick(where, (modifiers & shiftKey) != 0, theTE);
  2103.                 } else {
  2104.                     MyTEClick(where, 0, theTE);
  2105.                 }
  2106.             }
  2107.             gHandled = true;
  2108.             return noErr;
  2109.         }
  2110.     }
  2111.     
  2112.     if (curItem > 0 && (itemType & 0x7f) == editText && curTE != nil) {
  2113.         TESetSelect(0, 0, curTE);
  2114.         TEDeactivate(curTE);
  2115.         (**info).curItem = 0;
  2116.         TEActivate(dPeek->textH);
  2117.     }
  2118.     
  2119.     return noErr;
  2120. }
  2121.  
  2122.  
  2123.  
  2124. /*----------------------------------------------------------------------------
  2125.     Draggable
  2126.     
  2127.     Determine whether a mouse down event is on a draggable object in a 
  2128.     dialog window.
  2129.     
  2130.     Entry:    wind = pointer to dialog window.
  2131.             where = location of mouse down event, in local coordinates.
  2132.             modifiers = modifiers field from event record.
  2133.             
  2134.     Exit:    function result = true if object is draggable.
  2135. ----------------------------------------------------------------------------*/
  2136.  
  2137. static Boolean Draggable (WindowPtr wind, Point where, short modifiers)
  2138. {
  2139.     return false;
  2140. }
  2141.  
  2142.  
  2143.  
  2144. /*----------------------------------------------------------------------------
  2145.     Key 
  2146.     
  2147.     Handle a key down event for a dialog window.
  2148.             
  2149.     Entry:    wind = pointer to dialog window.
  2150.             theChar = ASCII code of key.
  2151.             theKey = keyboard code of key.
  2152.             modifiers = modifiers field from event record.
  2153.             
  2154.     Exit:    function result = error code.
  2155. ----------------------------------------------------------------------------*/
  2156.  
  2157. static OSErr Key (WindowPtr wind, unsigned char theChar, unsigned char theKey, short modifiers)
  2158. {
  2159.     DialogPeek dPeek;
  2160.     TWindow **info;
  2161.     TDialogItemInfo **itemInfo;
  2162.     TDialogItemInfo *pItemInfo;
  2163.     TEHandle theTE = nil, newTE;
  2164.     Boolean command, returnIsLegal = false, readOnly, isArrow;
  2165.     char *password;
  2166.     short itemType, item, numItems, editField = 0, newEditField;
  2167.     short selStart, selEnd, maxLength, pwLen;
  2168.     Handle itemHandle;
  2169.     Rect r;
  2170.     short curItem;
  2171.     ControlHandle vScroll;
  2172.     short delta;
  2173.     Boolean validChar;
  2174.     short defaultItem, cancelItem;
  2175.     char state;
  2176.     Boolean extraSpaceDeleted;
  2177.     short scrollIntoView;
  2178.     
  2179.     dPeek = (DialogPeek)wind;
  2180.     info = (TWindow**)GetWRefCon(wind);
  2181.     defaultItem = (**info).defaultItem;
  2182.     cancelItem = (**info).cancelItem;
  2183.     itemInfo = (**info).itemInfo;
  2184.     curItem = (**info).curItem;
  2185.     if (curItem > 0) {
  2186.         editField = curItem;
  2187.         theTE = (*itemInfo)[curItem-1].theTE;
  2188.     } else {
  2189.         editField = dPeek->editField + 1;
  2190.         theTE = dPeek->textH;
  2191.     }
  2192.     numItems = **(short**)(dPeek->items) + 1;
  2193.     if (editField > 0) {
  2194.         selStart = (**theTE).selStart;
  2195.         selEnd = (**theTE).selEnd;
  2196.         pItemInfo = &(*itemInfo)[editField-1];
  2197.         returnIsLegal = pItemInfo->returnIsLegal;
  2198.         maxLength = pItemInfo->maxLength;
  2199.         password = pItemInfo->password;
  2200.         readOnly = pItemInfo->readOnly;
  2201.         vScroll = pItemInfo->vScroll;
  2202.         validChar = pItemInfo->validChars[theChar];
  2203.         if (password != nil) pwLen = strlen(password);
  2204.     }
  2205.     
  2206.     isArrow = IsArrowKey(theChar);
  2207.     command = (modifiers & cmdKey) != 0;
  2208.     
  2209.     if (defaultItem != 0 && !command && 
  2210.         (theChar == returnKey && !returnIsLegal || theChar == enterKey))    
  2211.     {
  2212.         GetDialogItem(wind, defaultItem, &itemType, &itemHandle, &r);
  2213.         if ((itemType & itemDisable) == 0) {
  2214.             gItem = defaultItem;
  2215.             DlgFlashButton(wind, defaultItem);
  2216.         } else {
  2217.             gHandled = true;
  2218.         }
  2219.         return noErr;
  2220.     }
  2221.     
  2222.     if (cancelItem != 0 && ((!command && theKey == escapeKeyCode) ||
  2223.         (command && theChar == '.'))) 
  2224.     {
  2225.         GetDialogItem(wind, cancelItem, &itemType, &itemHandle, &r);
  2226.         if ((itemType & itemDisable) == 0) {
  2227.             gItem = cancelItem;
  2228.             DlgFlashButton(wind, cancelItem);
  2229.         } else {
  2230.             gHandled = true;
  2231.         }
  2232.         return noErr;
  2233.     }
  2234.     
  2235.     if (!isArrow && (command || editField == 0)) {
  2236.         state = MyHGetState(itemInfo);
  2237.         MyHLock(itemInfo);
  2238.         for (item = 1, pItemInfo = *itemInfo; 
  2239.             item <= numItems; 
  2240.             item++, pItemInfo++) 
  2241.         {
  2242.             if (tolower(theChar) == tolower(pItemInfo->keyEquivalent)) {
  2243.                 GetDialogItem(wind, item, &itemType, &itemHandle, &r);
  2244.                 if ((itemType & itemDisable) == 0) {
  2245.                     gItem = item;
  2246.                     DlgFlashButton(wind, item);
  2247.                 }
  2248.                 break;
  2249.             }
  2250.         }
  2251.         gHandled = true;
  2252.         MyHSetState(itemInfo, state);
  2253.         return noErr;
  2254.     }
  2255.     
  2256.     if (command) {
  2257.         SysBeep(0);
  2258.         return noErr;
  2259.     }
  2260.     
  2261.     if (editField == 0) return noErr;
  2262.     
  2263.     if (theKey == clearKeyCode) gEv->message = theChar = deleteKey;
  2264.     
  2265.     if (theChar == tabKey) {
  2266.         delta = (modifiers & shiftKey) != 0 ? -1 : +1;
  2267.         newEditField = editField + delta;
  2268.         while (newEditField != editField) {
  2269.             if (newEditField > numItems) newEditField = 1;
  2270.             if (newEditField <= 0) newEditField = numItems;
  2271.             GetDialogItem(wind, newEditField, &itemType, &itemHandle, &r);
  2272.             newTE = (*itemInfo)[newEditField-1].theTE;
  2273.             if ((itemType & 0x7f) == editText) {
  2274.                 TESetSelect(0, 0, theTE);
  2275.                 TEDeactivate(theTE);
  2276.                 (**info).curItem = 0;
  2277.                 SelectDialogItemText(wind, newEditField, 0, 0x7fff);
  2278.                 break;
  2279.             } else if (newTE != nil) {
  2280.                 TESetSelect(0, 0, theTE);
  2281.                 TEDeactivate(theTE);
  2282.                 if ((**theTE).teLength == 0) {
  2283.                     /* Goofy hack to erase insertion point when tabbing from an
  2284.                        empty field right after a window activate. Don't know why
  2285.                        this is required, but it is. */ 
  2286.                     r = (**theTE).viewRect;
  2287.                     EraseRect(&r);
  2288.                 }
  2289.                 (**info).curItem = newEditField;
  2290.                 TESetSelect(0, 0x7fff, newTE);
  2291.                 TEActivate(newTE);
  2292.                 break;
  2293.             }
  2294.             newEditField += delta;
  2295.         }
  2296.         gHandled = true;
  2297.         return noErr;
  2298.     }
  2299.     
  2300.     if (curItem > 0) {
  2301.         if (theChar == pageUpKey) {
  2302.             TEScrollScrollByPartCode(theTE, vScroll, inPageUp);
  2303.             gHandled = true;
  2304.             return noErr;
  2305.         }
  2306.         if (theChar == pageDownKey) {
  2307.             TEScrollScrollByPartCode(theTE, vScroll, inPageDown);
  2308.             gHandled = true;
  2309.             return noErr;
  2310.         }
  2311.         if (theChar == homeKey) {
  2312.             TEScrollScrollByPartCode(theTE, vScroll, kScrollToHome);
  2313.             gHandled = true;
  2314.             return noErr;
  2315.         }
  2316.         if (theChar == endKey) {
  2317.             TEScrollScrollByPartCode(theTE, vScroll, kScrollToEnd);
  2318.             gHandled = true;
  2319.             return noErr;
  2320.         }
  2321.     }
  2322.     
  2323.     if (theChar == forwardDelKey && !readOnly) {
  2324.         if (selStart < selEnd) {
  2325.             theChar = deleteKey;
  2326.         } else if (selEnd < (**theTE).teLength) {
  2327.             selEnd++;
  2328.             (**theTE).selEnd = selEnd;
  2329.             TEDelete(theTE);
  2330.             if (password != nil) 
  2331.                 BlockMoveData(password + selEnd, password + selStart, pwLen - selEnd + 1);
  2332.             gItem = editField;
  2333.             gHandled = true;
  2334.             return noErr;
  2335.         } else {
  2336.             gHandled = true;
  2337.             return noErr;
  2338.         }
  2339.     }
  2340.     
  2341.     if (theChar == deleteKey && selStart < selEnd && password == nil) {
  2342.         MyTEDelete(theTE, false, &extraSpaceDeleted);
  2343.         if (curItem > 0) TEScrollScrollSelectionIntoView(theTE, vScroll);
  2344.         gItem = editField;
  2345.         gHandled = true;
  2346.         return noErr;
  2347.     }
  2348.  
  2349.     if (!validChar && !isArrow && theChar != CR && theChar != deleteKey ||
  2350.         readOnly && !isArrow ||
  2351.         theChar == CR && !returnIsLegal) 
  2352.     {
  2353.         SysBeep(0);
  2354.         gHandled = true;
  2355.         return noErr;
  2356.     }
  2357.     
  2358.     if (validChar || theChar == CR) {
  2359.         if ((**theTE).teLength - (selEnd - selStart) + 1 > maxLength) goto exit;
  2360.         if (password != nil) {
  2361.             BlockMoveData(password + selEnd, password + selStart + 1, pwLen - selEnd + 1);
  2362.             *(password + selStart) = theChar;
  2363.             gEv->message = '•';
  2364.         }
  2365.     }
  2366.     
  2367.     if (theChar == deleteKey && password != nil) {
  2368.         if (selStart == selEnd && selStart > 0) selStart--;
  2369.         BlockMoveData(password + selEnd, password + selStart, pwLen - selEnd + 1);
  2370.     }
  2371.     
  2372.     if (isArrow) {
  2373.         TEArrowKey(theChar, modifiers, theTE, 0, &gPrevEvent, &scrollIntoView);
  2374.         if (curItem > 0) 
  2375.             TEScrollScrollRangeIntoView(theTE, scrollIntoView, scrollIntoView, vScroll);
  2376.         gItem = editField;
  2377.         gHandled = true;
  2378.     } else if (curItem > 0) {
  2379.         TEKey(theChar, theTE);
  2380.         TEScrollScrollSelectionIntoView(theTE, vScroll);
  2381.         gItem = editField;
  2382.         gHandled = true;
  2383.     }
  2384.  
  2385.     return noErr;
  2386.     
  2387. exit:
  2388.  
  2389.     StopAlertNumber(kStrNoMoreTyping);
  2390.     gHandled = true;
  2391.     return noErr;
  2392. }
  2393.  
  2394.  
  2395.  
  2396. /*----------------------------------------------------------------------------
  2397.     Command 
  2398.     
  2399.     Handle a command for a dialog window.
  2400.             
  2401.     Entry:    wind = pointer to dialog window.
  2402.             menu = the menu.
  2403.             item = the item.
  2404.             modifiers = modifiers field from event record.
  2405.     
  2406.     Exit:    function result = error code.
  2407. ----------------------------------------------------------------------------*/
  2408.  
  2409. static OSErr Command (WindowPtr wind, short menu, short item, short modifiers)
  2410. {
  2411.     DialogPeek dPeek;
  2412.     TWindow **info;
  2413.     TDialogItemInfo **itemInfo;
  2414.     TDialogItemInfo *pItemInfo;
  2415.     TEHandle theTE;
  2416.     char *password;
  2417.     short nBullets, editField = 0, pwLen, curItem;
  2418.     ControlHandle vScroll;
  2419.     Boolean returnIsLegal, pasteOK = true;
  2420.     long maxLength, selStart, selEnd;
  2421.     unsigned char *p, *pEnd;
  2422.     long scrapLen;
  2423.     Handle scrap;
  2424.     Boolean validChars[256];
  2425.     OSErr err = noErr;
  2426.     Boolean extraSpaceAddedInFront, extraSpaceDeleted;
  2427.     unsigned short teScrpLength;
  2428.     
  2429.     dPeek = (DialogPeek)wind;
  2430.     info = (TWindow**)GetWRefCon(wind);
  2431.     itemInfo = (**info).itemInfo;
  2432.     curItem = (**info).curItem;
  2433.     if (curItem > 0) {
  2434.         editField = curItem;
  2435.         theTE = (*itemInfo)[curItem-1].theTE;
  2436.     } else {
  2437.         editField = dPeek->editField + 1;
  2438.         theTE = dPeek->textH;
  2439.     }
  2440.     if (editField > 0) {
  2441.         selStart = (**theTE).selStart;
  2442.         selEnd = (**theTE).selEnd;
  2443.         pItemInfo = &(*itemInfo)[editField-1];
  2444.         password = pItemInfo->password;
  2445.         if (password != nil) pwLen = strlen(password);
  2446.         vScroll = pItemInfo->vScroll;
  2447.         maxLength = pItemInfo->maxLength;
  2448.         returnIsLegal = pItemInfo->returnIsLegal;
  2449.         BlockMoveData(pItemInfo->validChars, validChars, 256);
  2450.     }
  2451.  
  2452.  
  2453.     gHandled = true;
  2454.     if (menu != kEditMenu) return noErr;
  2455.     
  2456.     switch (item) {
  2457.         case kCutItem:
  2458.         case kCopyItem:
  2459.             if (password != nil) break;
  2460.             if (item == kCutItem) {
  2461.                 MyTECut(theTE);
  2462.                 gItem = editField;
  2463.                 if (curItem > 0) TEScrollScrollSelectionIntoView(theTE, vScroll);
  2464.             } else {
  2465.                 MyTECopy(theTE);
  2466.             }
  2467.             break;
  2468.         case kPasteItem:
  2469.             scrapLen = MyTEGetScrapLen();
  2470.             if (scrapLen == 0) break;
  2471.             if (scrapLen == 0x8000) goto exit1;
  2472.             scrap = TEScrapHandle();
  2473.             if ((**theTE).teLength - (selEnd - selStart) + scrapLen > maxLength) goto exit1;
  2474.             p = (unsigned char*)*scrap;
  2475.             pEnd = p + scrapLen;
  2476.             while (p < pEnd) {
  2477.                 if (*p < ' ') {
  2478.                     if (*p != returnKey || !returnIsLegal) {
  2479.                         pasteOK = false;
  2480.                         break;
  2481.                     }
  2482.                 } else if (!validChars[*p]) {
  2483.                     pasteOK = false;
  2484.                     break;
  2485.                 }
  2486.                 p++;
  2487.             }
  2488.             if (!pasteOK) goto exit2;    
  2489.             if (password == nil) {
  2490.                 if (validChars[' ']) {
  2491.                     MyTEPaste(nil, 0, theTE, maxLength, &extraSpaceAddedInFront);
  2492.                 } else {
  2493.                     TEPaste(theTE);
  2494.                 }
  2495.             } else {
  2496.                 teScrpLength = LMGetTEScrpLength();
  2497.                 BlockMoveData(password + selEnd,
  2498.                     password + selStart + teScrpLength,
  2499.                     pwLen - selEnd + 1);
  2500.                 BlockMoveData(*LMGetTEScrpHandle(), 
  2501.                     password + selStart,
  2502.                     teScrpLength);
  2503.                 nBullets = teScrpLength;
  2504.                 TEDelete(theTE);
  2505.                 while (nBullets--) TEInsert("•", 1, theTE);
  2506.             }
  2507.             gItem = editField;
  2508.             if (curItem > 0) TEScrollScrollSelectionIntoView(theTE, vScroll);
  2509.             break;
  2510.         case kClearItem:
  2511.             MyTEDelete(theTE, false, &extraSpaceDeleted);
  2512.             gItem = editField;
  2513.             if (curItem > 0) TEScrollScrollSelectionIntoView(theTE, vScroll);
  2514.             break;
  2515.         case kSelectAllItem:
  2516.             TESetSelect(0, 0x7fff, theTE);
  2517.             break;
  2518.     }
  2519.     
  2520.     return err;
  2521.     
  2522. exit1:
  2523.  
  2524.     StopAlertNumber(kStrScrapTooBig);
  2525.     return noErr;
  2526.     
  2527. exit2:
  2528.  
  2529.     StopAlertNumber(kStrScrapBadChar);
  2530.     return noErr;
  2531. }
  2532.  
  2533.  
  2534.  
  2535. /*----------------------------------------------------------------------------
  2536.     Close 
  2537.     
  2538.     Close a dialog window.
  2539.             
  2540.     Entry:    wind = pointer to dialog window.
  2541.     
  2542.     Exit:    function result = error code.
  2543. ----------------------------------------------------------------------------*/
  2544.  
  2545. static OSErr Close (WindowPtr wind)
  2546. {
  2547.     TWindow **info;
  2548.     TDialogItemInfo **itemInfo;
  2549.     short item, numItems;
  2550.     TDialogItemInfo *pItemInfo;
  2551.  
  2552.     gMyCurDialog = nil;
  2553.     info = (TWindow**)GetWRefCon(wind);
  2554.     itemInfo = (**info).itemInfo;
  2555.     numItems = CountDITL(wind);
  2556.     MyHLock(itemInfo);
  2557.     for (item = 1, pItemInfo = *itemInfo; 
  2558.         item <= numItems; 
  2559.         item++, pItemInfo++) 
  2560.     {
  2561.         if (pItemInfo->theTE != nil) TEDispose(pItemInfo->theTE);
  2562.     }
  2563.     MyDisposeHandle(itemInfo);
  2564.     MyDisposeHandle(info);
  2565.     DisposeDialog(wind);
  2566.     return noErr;
  2567. }
  2568.  
  2569.  
  2570.  
  2571. /*----------------------------------------------------------------------------
  2572.     Idle 
  2573.     
  2574.     Handle idle time tasks for a dialog window.
  2575.             
  2576.     Entry:    wind = pointer to dialog window.
  2577.     
  2578.     Exit:    cursorRgn = cursor region for WaitNextEvent mouse moved events
  2579.                 (not set or used with dialog windows).
  2580. ----------------------------------------------------------------------------*/
  2581.  
  2582. static void Idle (WindowPtr wind, RgnHandle cursorRgn)
  2583. {
  2584.     DialogPeek dPeek;
  2585.     TWindow **info;
  2586.     TDialogItemInfo **itemInfo;
  2587.     TDialogItemInfo *pItemInfo;
  2588.     Point where;
  2589.     Boolean setCursorToIBeam = false, password = false;
  2590.     short item, itemType, editField = 0;
  2591.     Handle itemHandle;
  2592.     unsigned long appleMenuFlags, editMenuFlags;
  2593.     TEHandle theTE, curTE;
  2594.     Boolean readOnly;
  2595.     short curItem;
  2596.     Rect box;
  2597.     Boolean somethingSelected;
  2598.  
  2599.     info = (TWindow**)GetWRefCon(wind);
  2600.     itemInfo = (**info).itemInfo;
  2601.     curItem = (**info).curItem;
  2602.     dPeek = (DialogPeek)wind;
  2603.     if (curItem > 0) {
  2604.         editField = curItem;
  2605.         curTE = (*itemInfo)[curItem-1].theTE;
  2606.         TEIdle(curTE);
  2607.     } else {
  2608.         editField = dPeek->editField + 1;
  2609.         curTE = dPeek->textH;
  2610.     }
  2611.     if (editField > 0) {
  2612.         pItemInfo = &(*itemInfo)[editField-1];
  2613.         readOnly = pItemInfo->readOnly;
  2614.         password = pItemInfo->password != nil;
  2615.     }
  2616.     
  2617.     GetMouse(&where);
  2618.     item = FindDialogItem(wind, where) + 1;
  2619.     if (item > 0) {
  2620.         theTE = (*itemInfo)[item-1].theTE;
  2621.         GetDialogItem(wind, item, &itemType, &itemHandle, &box);
  2622.         if ((itemType & 0x7f) == editText) {
  2623.             setCursorToIBeam = true;
  2624.         } else if (theTE != nil) {
  2625.             box = (**theTE).viewRect;
  2626.             setCursorToIBeam = PtInRect(where, &box);
  2627.         }
  2628.     }
  2629.     SetCursor(setCursorToIBeam ? &gIBeamCurs : &qd.arrow);
  2630.     
  2631.     appleMenuFlags = (**info).movableModal ? kAppleOnlyAboutDisabled : kAppleAllDisabled;
  2632.     if (editField > 0) {
  2633.         editMenuFlags = 0;
  2634.         somethingSelected = (**curTE).selEnd > (**curTE).selStart;
  2635.         if (somethingSelected) editMenuFlags |= kCopyMask;
  2636.         if ((**curTE).teLength > 0) editMenuFlags |= kSelectAllMask;
  2637.         if (!readOnly) {
  2638.             if (MyTEGetScrapLen() > 0) editMenuFlags |= kPasteMask;
  2639.             if (somethingSelected) editMenuFlags |= kCutMask | kClearMask;
  2640.         }
  2641.         if (password) editMenuFlags &= ~(kCutMask | kCopyMask);
  2642.         if (editMenuFlags != 0) editMenuFlags |= kEntireMenuMask;
  2643.         SetMenusTo(appleMenuFlags, 0, editMenuFlags, 0, 0, 0);
  2644.     } else {
  2645.         SetMenusTo(appleMenuFlags, 0, 0, 0, 0, 0);
  2646.     }
  2647. }
  2648.  
  2649.  
  2650.  
  2651. /*----------------------------------------------------------------------------
  2652.     Help 
  2653.     
  2654.     Handle help balloons for a dialog window.
  2655.             
  2656.     Entry:    wind = pointer to dialog window.
  2657.             where = current mouse location in local coordinates.
  2658.             
  2659.     This function doesn't do anything. Help balloons for dialog windows
  2660.     are done by the Dialog Manager using 'hdlg' resources.
  2661. ----------------------------------------------------------------------------*/
  2662.  
  2663. static void Help (WindowPtr wind, Point where)
  2664. {
  2665. }
  2666.  
  2667.  
  2668.  
  2669. /*----------------------------------------------------------------------------
  2670.     InitDialogDispatchTable 
  2671.     
  2672.     Initialize the dispatch table for dialog windows.
  2673. ----------------------------------------------------------------------------*/
  2674.  
  2675. void InitDialogDispatchTable (void)
  2676. {
  2677.     TDispatch *d;
  2678.     
  2679.     d = &gDispatch[kDialog];
  2680.     
  2681.     d->activate = Activate;
  2682.     d->update = Update;
  2683.     d->mouse = Mouse;
  2684.     d->draggable = Draggable;
  2685.     d->key = Key;
  2686.     d->grow = nil;
  2687.     d->zoom = nil;
  2688.     d->command = Command;
  2689.     d->close = Close;
  2690.     d->idle = Idle;
  2691.     d->help = Help;
  2692.     
  2693.     gAutoScrollUPP = NewTEClickLoopProc(AutoScroll);
  2694.     gScrollActionUPP = NewControlActionProc(ScrollAction);
  2695.     gDialogFilterUPP = NewModalFilterProc(DialogFilter);
  2696.     gScrollingTextFieldUserItemUPP = NewUserItemProc(ScrollingTextFieldUserItem);
  2697.     gDlgGrayBorderItemUPP = NewUserItemProc(DlgGrayBorderItem);
  2698.     gDlgDefaultButtonOutlineItemUPP = NewUserItemProc(DlgDefaultButtonOutlineItem);
  2699.     gAEIdleProcUPP = NewAEIdleProc(AEIdleProc);
  2700. }
  2701.